package com.uwantsoft.business.service.domain.park;

import com.uwantsoft.business.facade.dto.parking.ParkDetailDto;
import com.uwantsoft.business.facade.dto.parking.ParkFormDto;
import com.uwantsoft.business.facade.dto.parking.ParkOverViewDto;
import com.uwantsoft.business.service.domain.addresses.LatLng;
import com.uwantsoft.business.service.domain.city.City;
import com.uwantsoft.business.service.infrastructure.ParkRepository;
import com.uwantsoft.util.AbstractEntity;
import com.uwantsoft.util.JodaUtils;
import com.uwantsoft.util.ParkCodeGenerator;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Configurable;

import javax.annotation.Resource;
import javax.persistence.*;
import java.math.BigDecimal;

/**
 * @author LeiPeichen.
 */
@Entity
@Table(name = "park")
@Configurable(autowire = Autowire.BY_NAME)
public class Park extends AbstractEntity{

    @Resource(name = "hibernateParkRepository")
    private transient ParkRepository parkRepository;

    @Column(name = "registration_code",unique = true)
    private String registrationCode;
    @Column(name = "name")
    private String name;

    @ManyToOne(targetEntity = City.class)
    @JoinColumn(name="city_id")
    private City city;
    @Column(name = "address")
    private String address;
    @Embedded
    private LatLng latLng;
    @Column(name = "stall_number")
    private int stallNumber;
    @Column
    @Enumerated(value = EnumType.STRING)
    private ParkStatus status;
    @Column(name = "start_price")
    private BigDecimal startPrice;
    @Column(name = "unit_price")
    private BigDecimal unitPrice;
    @Column(name = "order_note",columnDefinition="TEXT")
    private String orderNote;
    @Column(name = "queue_note",columnDefinition="TEXT")
    private String queueNote;
    public String name() {
        return name;
    }

    public String address(){
        return address;
    }

    public String stallNumberAsText(){
        return stallNumber + "";
    }

    public String startPriceAsText(){
        if(startPrice != null){
            return startPrice.toString();
        }
        return "";
    }

    public String unitPriceAsText(){
        if(unitPrice != null){
            return unitPrice.toString();
        }
        return "";
    }

    public String orderNote() {
        return orderNote;
    }

    public String queueNote() {
        return queueNote;
    }

    public String registrationCode(){
        return registrationCode;
    }

    public ParkFormDto convert(){
        ParkFormDto parkFormDto = new ParkFormDto();
        parkFormDto.setGuid(this.guid());
        parkFormDto.setName(this.name());
        parkFormDto.setAddress(this.address());
        parkFormDto.setCityGuid(this.city.guid());
        parkFormDto.setLat(this.latLng.latitude());
        parkFormDto.setIng(this.latLng.longitude());
        parkFormDto.setStallNumber(this.stallNumberAsText());
        parkFormDto.setRegistrationTime(JodaUtils.formatDateTime(this.createTime()));
        parkFormDto.setStartPrice(this.startPriceAsText());
        parkFormDto.setUnitPrice(this.unitPriceAsText());
        parkFormDto.setOrderNote(this.orderNote());
        parkFormDto.setQueueNote(this.queueNote());
        return parkFormDto;
    }

    public static Park createPark(ParkFormDto parkFormDto,City city) {
        Park park = new Park();
        park.name = parkFormDto.getName();
        if(city != null){
            park.city = city;
        }
        park.address = parkFormDto.getAddress();
        LatLng newlatlng = new LatLng();
        newlatlng.latLng(parkFormDto.getLat(),parkFormDto.getLng());
        park.latLng = newlatlng;
        park.startPrice = new BigDecimal(parkFormDto.getStartPrice());
        park.unitPrice = new BigDecimal(parkFormDto.getUnitPrice());
        park.stallNumber = Integer.parseInt(parkFormDto.getStallNumber());
        park.orderNote = parkFormDto.getOrderNote();
        park.queueNote = parkFormDto.getQueueNote();
        park.registrationCode = park.createRegistrationCode();
        park.status = ParkStatus.AVAILABLE;
        return park;
    }
    public void update(ParkFormDto parkFormDto,City city) {
        this.name = parkFormDto.getName();
        if(city != null){
            this.city = city;
        }
        this.address = parkFormDto.getAddress();
        LatLng newlatlng = new LatLng();
        newlatlng.latLng(parkFormDto.getLat(),parkFormDto.getLng());
        this.latLng = newlatlng;
        this.startPrice = new BigDecimal(parkFormDto.getStartPrice());
        this.unitPrice = new BigDecimal(parkFormDto.getUnitPrice());
        this.stallNumber = Integer.parseInt(parkFormDto.getStallNumber());
        this.queueNote = parkFormDto.getQueueNote();
        this.orderNote = parkFormDto.getOrderNote();

    }

    public ParkOverViewDto convertParkOverView() {
        ParkOverViewDto parkOverViewDto = new ParkOverViewDto();
        parkOverViewDto.setGuid(this.guid());
        parkOverViewDto.setName(this.name());
        parkOverViewDto.setCity(this.city.name());
        parkOverViewDto.setAddress(this.address());
        parkOverViewDto.setStallNumber(this.stallNumberAsText());
        parkOverViewDto.setStartPrice(startPriceAsText());
        parkOverViewDto.setUnitPrice(unitPriceAsText());
        parkOverViewDto.setStatus(this.status.getValue());
        parkOverViewDto.setRegistrationTime(JodaUtils.formatDateTime(this.createTime()));
        parkOverViewDto.setRegistrationCode(this.registrationCode());
        parkOverViewDto.setActive(this.active());
        return parkOverViewDto;
    }

    public String createRegistrationCode(){
        DateTime todayStart = JodaUtils.todayStart();
        DateTime todayEnd = JodaUtils.todayEnd();
        int amount = parkRepository.findParkAmount(todayStart, todayEnd);
        return ParkCodeGenerator.generate(this.city.code(),amount);
    }

    public ParkDetailDto convertParkDetail() {
        ParkDetailDto parkDetailDto = new ParkDetailDto();
        parkDetailDto.setName(this.name());
        parkDetailDto.setCity(this.city.name());
        parkDetailDto.setAddress(this.address());
        parkDetailDto.setLat(this.latLng.latitude());
        parkDetailDto.setLng(this.latLng.longitude());
        parkDetailDto.setStallNumber(this.stallNumberAsText());
        parkDetailDto.setStartPrice(this.startPriceAsText());
        parkDetailDto.setUnitPrice(this.unitPriceAsText());
        parkDetailDto.setStatus(this.status.getValue());
        parkDetailDto.setOrderNote(this.orderNote());
        parkDetailDto.setRegistrationTime(JodaUtils.formatDateTime(this.createTime()));
        parkDetailDto.setRegistrationCode(this.registrationCode());
        return parkDetailDto;
    }

    /**
     * test
     * @return
     */
    public static Park testInstanceParkOne(City city){
        Park park = new Park();
        park.name = "IFS";
        park.city = city;
        LatLng newlatlng = new LatLng();
        newlatlng.latLng("100","90");
        park.latLng = newlatlng;
        park.stallNumber = 100;
        park.status = ParkStatus.AVAILABLE;
        park.registrationCode = park.createRegistrationCode();
        return park;
    }
}
